package com.yn.sample.execution.memory;

import com.yn.sample.execution.objectfactory.ObjectInfo;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;

@Component
public class MemoryManagement {

    /**
     * 8kb的eden区域
     */
    public static ByteBuffer eden = ByteBuffer.allocate(8 * 1024);

    public static ByteBuffer survivor1 = ByteBuffer.allocate(1024);
    public static ByteBuffer survivor2 = ByteBuffer.allocate(1024);

    private static int globalAllocateIndex = 0;


    /**
     * 返回内存中的开始地址
     * @param size
     * @return
     */
    public static ObjectInfo allocateBytebuffer(int size) {
        /**
         * todo:判断内存是否足够
         */

        /**
         *
         */
        ObjectInfo objectInfo = new ObjectInfo();
        objectInfo.setObjectOffsetInByteBuffer(globalAllocateIndex);
        objectInfo.setSize(size);
        objectInfo.setEden(eden);

        /**
         * 分配后，索引往前调整
         */
        globalAllocateIndex += size;


        return objectInfo;
    }


    /**
     * 获取field的value
     * @param objectOffsetInByteBuffer
     * @param fieldOffset
     * @param fieldType
     * @return
     */
    public static Object getFieldValueFromMemory(int objectOffsetInByteBuffer, Integer fieldOffset,
                                                 Class<?> fieldType) {
        eden.position(objectOffsetInByteBuffer + fieldOffset);
        if (fieldType.isPrimitive()) {
            if (fieldType == Integer.TYPE) {
                return eden.getInt();
            } else if (fieldType == Byte.TYPE) {
                return eden.get();
            } else if (fieldType == Long.TYPE) {
                return eden.getLong();
            } else if (fieldType == Float.TYPE) {
                return eden.getFloat();
            } else if (fieldType == Double.TYPE) {
                return eden.getDouble();
            } else if (fieldType == Short.TYPE) {
                return eden.getShort();
            } else if (fieldType == Character.TYPE) {
                return eden.getChar();
            } else if (fieldType == Boolean.TYPE) {
                return eden.getShort();
            }
        } else if (fieldType.isArray()) {
            /**
             * 当成一个引用
             */
            return eden.getInt();
        } else {
            /**
             * 引用数据类型
             */
            return eden.getInt();
        }
        return null;
    }



    /**
     * 获取field的value
     * @param objectOffsetInByteBuffer
     * @param fieldOffset
     * @param fieldType
     * @return
     */
    public static Object setFieldValue2Memory(int objectOffsetInByteBuffer,
                                              Integer fieldOffset,
                                              Class<?> fieldType,
                                              Object value) {
        eden.position(objectOffsetInByteBuffer + fieldOffset);
        if (fieldType.isPrimitive()) {
            if (fieldType == Integer.TYPE) {
                return eden.putInt((Integer) value);
            } else if (fieldType == Byte.TYPE) {
                return eden.put((Byte) value);
            } else if (fieldType == Long.TYPE) {
                return eden.putLong((Long) value);
            } else if (fieldType == Float.TYPE) {
                return eden.putFloat((Float) value);
            } else if (fieldType == Double.TYPE) {
                return eden.putDouble((Double) value);
            } else if (fieldType == Short.TYPE) {
                return eden.putShort((Short) value);
            } else if (fieldType == Character.TYPE) {
                return eden.putChar((Character) value);
            } else if (fieldType == Boolean.TYPE) {
                return eden.putShort((Short) value);
            }
        } else if (fieldType.isArray()) {
            /**
             * 当成一个引用
             */
            return eden.putInt((Integer) value);
        } else {
            /**
             * 引用数据类型
             */
            return eden.putInt((Integer) value);
        }


        return null;
    }
}
